﻿using System;

namespace Microsoft.Extensions.Logging
{
    /// <summary>
    /// 日志扩展类，使得日志输出可以使用插值语法
    /// </summary>
    public static class LoggerExtensions
    {
        /// <summary>
        /// 记录严重级别的日志，支持插值字符串
        /// </summary>
        /// <param name="logger">ILogger 实例，用于记录日志</param>
        /// <param name="formattableString">可插值的字符串，支持类似 $"a={a,3:C}" 的格式</param>
        /// <param name="exception">可选，与日志关联的异常信息</param>
        /// <param name="eventId">可选，用于标识日志事件的事件 ID</param>
        public static void LogInterpolatedCritical(this ILogger logger, FormattableString formattableString,
            Exception? exception = default, EventId eventId = default)
        {
            // todo: 插值字符串支持$"a={a,3:C}"这样的写法，目前这样不支持，需要解析，参考https://gist.github.com/artemious7/c7d9856e128a8b2e9e92d096ca0e69ee#file-serilog-loggerstringinterpolationextensions-cs
            // 用于指示系统遇到了严重的错误，可能导致应用程序无法继续运行或者已经崩溃的情况。
            logger.LogCritical(eventId, exception, formattableString.Format, formattableString.GetArguments());
        }


        /// <summary>
        /// 记录错误级别的日志，支持插值字符串
        /// </summary>
        /// <param name="logger">ILogger 实例，用于记录日志</param>
        /// <param name="formattableString">可插值的字符串，支持类似 $"a={a,3:C}" 的格式</param>
        /// <param name="exception">可选，与日志关联的异常信息</param>
        /// <param name="eventId">可选，用于标识日志事件的事件 ID</param>
        public static void LogInterpolatedError(this ILogger logger, FormattableString formattableString,
            Exception? exception = default, EventId eventId = default)
        {
            // 用于指示系统遇到了错误，但是应用程序仍然能够继续运行，不会导致应用程序崩溃
            logger.LogError(eventId, exception, formattableString.Format, formattableString.GetArguments());
        }

        /// <summary>
        /// 记录警告级别的日志，支持插值字符串
        /// </summary>
        /// <param name="logger">ILogger 实例，用于记录日志</param>
        /// <param name="formattableString">可插值的字符串，支持类似 $"a={a,3:C}" 的格式</param>
        /// <param name="exception">可选，与日志关联的异常信息</param>
        /// <param name="eventId">可选，用于标识日志事件的事件 ID</param>
        public static void LogInterpolatedWarning(this ILogger logger, FormattableString formattableString,
            Exception? exception = default, EventId eventId = default)
        {
            // 用于指示系统遇到了一些不太严重的问题或者潜在的错误，但是应用程序仍然可以继续正常运行
            logger.LogWarning(eventId, exception, formattableString.Format, formattableString.GetArguments());
        }

        /// <summary>
        /// 记录信息级别的日志，支持插值字符串
        /// </summary>
        /// <param name="logger">ILogger 实例，用于记录日志</param>
        /// <param name="formattableString">可插值的字符串，支持类似 $"a={a,3:C}" 的格式</param>
        /// <param name="exception">可选，与日志关联的异常信息</param>
        /// <param name="eventId">可选，用于标识日志事件的事件 ID</param>
        public static void LogInterpolatedInformation(this ILogger logger, FormattableString formattableString,
            Exception? exception = default, EventId eventId = default)
        {
            // 用于记录系统运行时的一般信息，例如操作成功完成、服务启动等
            logger.LogInformation(eventId, exception, formattableString.Format, formattableString.GetArguments());
        }

        /// <summary>
        /// 记录调试级别的日志，支持插值字符串
        /// </summary>
        /// <param name="logger">ILogger 实例，用于记录日志</param>
        /// <param name="formattableString">可插值的字符串，支持类似 $"a={a,3:C}" 的格式</param>
        /// <param name="exception">可选，与日志关联的异常信息</param>
        /// <param name="eventId">可选，用于标识日志事件的事件 ID</param>
        public static void LogInterpolatedDebug(this ILogger logger, FormattableString formattableString,
            Exception? exception = default, EventId eventId = default)
        {
            // 用于记录详细的调试信息，主要用于开发和调试阶段，对于普通用户来说通常是不需要关注的
            logger.LogDebug(eventId, exception, formattableString.Format, formattableString.GetArguments());
        }


        /// <summary>
        /// 记录跟踪级别的日志，支持插值字符串
        /// </summary>
        /// <param name="logger">ILogger 实例，用于记录日志</param>
        /// <param name="formattableString">可插值的字符串，支持类似 $"a={a,3:C}" 的格式</param>
        /// <param name="exception">可选，与日志关联的异常信息</param>
        /// <param name="eventId">可选，用于标识日志事件的事件 ID</param>
        public static void LogInterpolatedTrace(this ILogger logger, FormattableString formattableString,
            Exception? exception = default, EventId eventId = default)
        {
            // 用于记录跟踪信息，通常包含非常详细的调试信息，适用于对系统性能进行深入分析和调优
            logger.LogTrace(eventId, exception, formattableString.Format, formattableString.GetArguments());
        }

    }
}
